<?php

namespace App\Services\YunXinCloud;

use App\Actions\MessageAction;
use App\Actions\PaycallAction;
use App\Dao\AppUpgradeDao;
use App\Dao\ClosenessDao;
use App\Dao\FollowListDao;
use App\Dao\Mongodb\UserChatFlagDao;
use App\Dao\PayCallDao;
use App\Dao\UserDao;
use App\Job\Delay\removeBlackScreenDelayQueueJob;
use App\Model\AdUnmask;
use App\Model\Anchor;
use App\Model\AutoReply;
use App\Model\Closeness;
use App\Model\Filtration;
use App\Model\LogScript;
use App\Model\NotifyCopy;
use App\Model\Setting;
use App\Model\User;
use App\Model\UserBlacklist;
use App\Model\UserFirstAccost;
use App\Model\UserPunish;
use App\Model\UserToken;
use App\Model\YunxinAudio;
use App\Services\Mission\MissionQueue;
use App\Services\PushMessageService;
use App\Utils\FunUtil;
use App\Utils\LoggerUtil;
use App\Utils\MongoDBClient;
use App\Utils\RedisClient;
use Throwable;
use function Hyperf\Translation\trans;

class NotifyService
{

    /**
     * Note - 云信消息第三方回调
     * DateTime 2024/7/29 15:22
     * User Admin
     * @param array $requestBody
     * @return false|string
     */
    public function callback(array $requestBody)
    {
        $wyyClient = new WyyClientService();
        try {
            LoggerUtil::write('yun_xin_callback', $requestBody);
            $contentTypeArr = [
                "TEXT" => 1,       //1-文字消息
                "AUDIO" => 2,      //2-语音消息
                "PICTURE" => 3,    //3-图片
            ];
            $msgType = $requestBody["msgType"];
            $uid = $requestBody["fromAccount"] ?? 0;
            $user_id = $requestBody["to"];
            $content_type = $contentTypeArr[$msgType];
            $content = $requestBody["body"];
            $eventType = $requestBody["eventType"];
            $ext = $requestBody["ext"];
            $ext = json_decode($ext, true);

            if ($eventType != 1) {
                return $wyyClient->responseJson(0, 20000, "", []);
            }
            $userDao = UserDao::getInstance();
            $userInfo = $userDao->findUserInfoCache($uid);

            if (isset($ext['msg'][0]['user_info']['language']) && $ext['msg'][0]['user_info']['language'] != '') {
                $language = $ext['msg'][0]['user_info']['language'];
            } else {
                $uExt2Array = $userInfo['ext2'];
                $language = $uExt2Array['language'] ?? 'en';
            }

            // 禁言判断
            if (FunUtil::gagUserChat($uid)) {
                throw new \Exception(trans("desc.账号异常正在风险审核中，审核通过才可以使用该功能，请耐心等候。", [], $language), 401);
            }

            //不能发消息给自己
            if ($user_id == $uid) {
                throw new \Exception(trans("desc.您不能发消息给自己", [], $language), 402);
            }

            if (in_array($content_type, [2, 3])) {
                $attach = $requestBody["attach"];
                $attach = json_decode($attach, true);
                $ext["msg"][0]['content'] = $attach['url'];
                if ($content_type == 3) {
                    $ext["msg"][0]['w'] = $attach['w'];
                    $ext["msg"][0]['h'] = $attach['h'];
                }
            }

            $mongo = MongoDBClient::getInstance();
            //设置消息已读
            if ($ext['event'] == 'message_receipt') {
                $changeWhere['uid'] = intval($user_id);
                $changeWhere['receive_uid'] = intval($uid);
                $set['$set'] = ['look' => 1];
                $mongo->update('tb_user_chat_v2', $changeWhere, $set, true, false);
            }

            // 我拉黑的用户id列表
            $my_black = UserBlacklist::getBlackFooUids($uid);
            if (in_array($user_id, $my_black)) {
                throw new \Exception(trans("desc.您已将对方加入黑名单", [], $language), 406);
            } else {
                // 拉黑的我的用户id列表
                $user_black = UserBlacklist::getBlackBarUids($uid);
                if (in_array($user_id, $user_black)) {
                    throw new \Exception(trans("desc.对方已将您加入黑名单", [], $language), 406);
                }
            }


            $from = $userInfo["from"];
            $version_code = $userInfo["version_code"];
            $channel = $ext['msg'][0]["channel_number"];
            $content_type = $ext['msg'][0]["content_type"];
            $ip = $userInfo["last_login_ip"];


            $appupgradeModel = new AppUpgradeDao();

            //禁止同性发消息
            if (!$appupgradeModel->isShowSameSexComment($from, $version_code, $channel, $ip)) {

                if ($userInfo["sex"] == 1 && !$userInfo['noble'] && !$userInfo['super_noble'] && $content_type == 3) {
                    throw new \Exception(trans("desc.请先开通VIP", [], $language), 407);
                }
                $target_user = $userDao->findUserInfoCache($user_id);
                if (!empty($target_user) && $target_user["sex"] == $userInfo["sex"]) {
                    throw new \Exception(trans("desc.禁止发送消息给同性", ['from' => $from, 'version_code' => $version_code, 'channel' => $channel], $language), 404);
                }
            }

            $suggestion = 0;
            $requestID = '';
            $suggestionMsg = '';


            // 收费版
            if (CHARGE_CALL_VERSION &&
                !$appupgradeModel->isHideMaleChatCost($from, $version_code, $channel, $ip, $uid) &&
                !FollowListDao::getInstance()->isMutual($uid, $user_id) &&
                $ext['event'] != 'message_receipt'
            ) {
                if ($userInfo["sex"] == 1) {
                    //判断用户剩余金币
                    // $text_price = (new AnchorModel())->getValue($user_id, "greet_price");
                    $textPrice = Anchor::query()->where('id', $user_id)->value('greet_price');
                    $userGiftCount = User::query()->selectRaw('gift_count+chat_count+recharge_send_count+sys_send_count as count')->where('id', $uid)->value('count');
                    if ($userGiftCount < $textPrice) {
                        throw new \Exception(trans("desc.您的金币余额不足", [], $language), 405);
                    }
                }
            }

            if ($content_type == 1) {
                //快捷用语不需要过滤
                // $autoReplyModel = new AutoReplyModel();
                // $autoReplyData = $autoReplyModel->find('id,content', 'content = ? or en_content = ? or hk_content = ?', [$content, $content, $content]);
                $autoReplyData = AutoReply::selectRaw('id')
                    ->where('status', 2)
                    ->where(function ($query) use ($content) {
                        $query->orWhere('content', $content)->orWhere('en_content', $content)->orWhere('hk_content', $content);
                    })->first();
                if (empty($autoReplyData)) {
                    if ((new Filtration())->isExistIllega($content, 1)) { // 后台关键字过滤
                        $suggestion = 2;
                        $suggestionMsg = trans('desc.存在敏感词', [], $language);
                    }
                }
            }
            $ext['msg'][0]['taskID'] = $requestID;
            $ext['msg'][0]['suggestion'] = $suggestion;
            $ext['msg'][0]['suggestionMsg'] = $suggestionMsg;

            if (preg_match('/\b(客服|转账)\b/i', $content)) {
                $callBack['code'] = '1001';
            }

            // 是否风险限制用户
            $is_limit = 0;
            $redis = RedisClient::getInstance();
            // 版本是否屏蔽付费聊天
            if (!$appupgradeModel->isHideMaleChatCost($from, $version_code, $channel, $ip, $uid)) {
                $target_user = $userDao->findUserInfoCache($user_id);
                if (!empty($target_user) && $target_user["sex"] == $userInfo["sex"]) {
                    throw new \Exception(trans("desc.禁止发送消息给同性", ['from' => $from, 'version_code' => $version_code, 'channel' => $channel], $language), 404);
                    // throw new \Exception('禁止发送消息给同性' . sprintf("%s:%s:%s", $from, $version_code, $channel), 404);
                }

                //发消息收费
                if ($userInfo["sex"] == 1) {
                    // 亲密度
                    $closeness = ClosenessDao::read($uid, $user_id);
                    $closenessLevel = ClosenessDao::getClosenessLevel($closeness + ($redis->hGet("tmp_closeness:{$uid}", $user_id) ?: 0));
                    if (CHARGE_CALL_VERSION && $content_type == 2 && $closenessLevel < 2) {
                        throw new \Exception("亲密度等级不足", 401);
                    }
                    if (CHARGE_CALL_VERSION && $content_type == 3 && $closenessLevel < 3) {
                        throw new \Exception("亲密度等级不足", 401);
                    }

                    // 风险用户聊天判断
                    if ($ext['event'] != 'message_receipt' && $userInfo['not_show'] == 1) {
                        $is_limit = FunUtil::chatLimit($uid, $user_id, $closeness);
                    }

                    if ($ext['event'] != 'user_conn') {
                        LoggerUtil::write('yun_xin_callback_error', $requestBody);
                    }
                    //兆勇需求，message_receipt标志的消息不收费
                    if (CHARGE_CALL_VERSION && !FollowListDao::getInstance()->isMutual($uid, $user_id) && ($ext['event'] != 'message_receipt')) {
                        $textPrice = Anchor::query()->where('id', $user_id)->value('greet_price');
                        //判断用户剩余金币
                        $userGiftCount = User::query()->selectRaw('gift_count+chat_count+recharge_send_count+sys_send_count as count')->where('id', $uid)->value('count');
                        if ($userGiftCount < $textPrice) {
                            throw new \Exception(trans("desc.您的金币余额不足", [], $language), 405);
                        }

                        //扣除男用户金币，给女用户加积分（121版本暂时不给女用户加积分）
                        $res = (new PaycallAction())->payForMessage($uid, $user_id, $textPrice, SINGLE_MESSAGE_RATE, $ext['msg'][0]["message_id"], $is_limit);
                        if ($res['code']) {
                            throw new \Exception($res['msg'], 405);
                        } else {
                            if ($is_limit) {
                                // 记录风险用户扣费 8小时后退回
                                $insert = [
                                    'uid' => $uid,
                                    'to_uid' => $user_id,
                                    'type' => 1,    // 1消息 2礼物
                                    'gold' => $res['gold'],
                                    'gold_from' => $res['gold_from'] ?? '',
                                    'expend_id' => $res['expend_id'],
                                    'ctime' => time(),
                                    'is_return' => 0,
                                    'return_time' => 0,
                                ];
                                $mongo->insert('tb_limit_user_message', $insert);
                                return $wyyClient->responseJson(1, 200, '');
                            }

                            // 女用户显示实际所得积分
                            $ext["msg"][0]['message_price'] = $res['profit'];
                        }

                    } else {
                        // 免费消息加亲密度
                        if ($ext['event'] != 'message_receipt') {
                            $closeness = $redis->get("freeMsg:closeness_" . $uid . "_" . $user_id);
                            if (!$closeness || $closeness < 12) {
                                // 记录用户亲密度
                                ClosenessDao::write($uid, $user_id, SINGLE_MESSAGE_COST);
                                $overTime = strtotime(date("Y-m-d 23:59:59")) - time();
                                $redis->setex("freeMsg:closeness_" . $uid . "_" . $user_id, $overTime, intval($closeness) + SINGLE_MESSAGE_COST);
                            }
                        }
                        // 免费消息处理
                        $ext["msg"][0]['message_price'] = 0;
                    }
                } else {
                    // 女用户发送消息
                    // 亲密度
                    $closeness = ClosenessDao::read($user_id, $uid);
                    // 风险用户聊天判断
                    if ($ext['event'] != 'message_receipt') {
                        if ($userInfo['not_show'] == 1 && FunUtil::chatLimit($uid, $user_id, $closeness)) {
                            return $wyyClient->responseJson(1, 200, '');
                        };

                        // 判断男用户是风险用户 收不到消息
                        if (FunUtil::chatLimit($user_id, $uid, $closeness)) {
                            return $wyyClient->responseJson(1, 200, '');
                        }
                    }

                }
            } else {
                // 审核环境男用户发消息判断对方环境为正式的不发送
                LoggerUtil::write("yun_xin_callback_audit", compact('uid', 'channel', 'version_code', 'ip'));
                // $targetUser = $userModel->find("id,version_code,channel,last_login_ip", "id=?", [$user_id]);
                $targetUser = User::query()->select(['version_code', 'channel', 'last_login_ip'])->where('id', $user_id)->first();

                if (!$appupgradeModel->isHideMaleChatCost(1, $targetUser['version_code'], $targetUser['channel'], $targetUser['last_login_ip'], $user_id)) {
                    return $wyyClient->responseJson(1, 200, '');
                }
            }

            // 获取消息嫌疑类型
            $callBack['code'] = $callBack['code'] ?? '0';
            $callBack['msg'] = '';
            $callBack['is_success'] = '1';
            // 删除多余字段，防止长度超出1024
            unset($ext['msg'][0]['channel_number'], $ext['msg'][0]['packageName'], $ext['msg'][0]['version_code'], $ext['msg'][0]['from'], $ext['msg'][0]['user_info']['level']);

            // code也要带到对方的im消息里面
            $ext["msg"][0]['code'] = $callBack['code'];
            $ext["msg"][0]['suspect_code'] = $callBack['code'];
            $replaceArr = [];
            $replaceArr["ext"] = json_encode($ext, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
            if ($content_type == 1) {
                $replaceArr["body"] = $content;
            }

            if ($callBack['code'] != 0) {
                return $wyyClient->responseJson(0, 20000, json_encode($callBack), $replaceArr);
            } else {
                return $wyyClient->responseJson(0, 20000, '', $replaceArr);
            }
        } catch (Throwable $e) {
            $response = [
                'uid' => $uid,
                'user_id' => $user_id,
                "code" => $e->getCode(),
                "msg" => $e->getMessage(),
                'request_body' => $requestBody
            ];
            LoggerUtil::write('yun_xin_callback_abnormal', $response);
            unset($response['uid'], $response['user_id'], $response['request_body']);
            $response['is_success'] = '0';
            return $wyyClient->responseJson(1, 200, json_encode($response, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
        }

    }


    /**
     * Note - 云信消息抄送
     * DateTime 2024/7/30 11:54
     * User Admin
     * @param array $requestBody
     * @param $headers
     * @return false|string
     */
    public function copy(array $requestBody, $headers)
    {
        $wyyClient = new WyyClientService();
        try {
            LoggerUtil::write('yun_xin_copy', $requestBody);

            $CurTime = $headers['CurTime'];
            $MD5 = $headers['MD5'];
            $CheckSum = $headers['CheckSum'];
            $eventType = $requestBody["eventType"];
            $convType = $requestBody["convType"];
            $msgType = $requestBody["msgType"];
            $redis = RedisClient::getInstance();
            if ($eventType == 1) {
                $notify_copy_id = NotifyCopy::query()->insertGetId([
                    'event_type' => $eventType,
                    'conv_type' => $convType,
                    'msg_type' => $msgType,
                    'uid' => $requestBody['fromAccount'] ?? 0,
                    'user_id' => $requestBody['to'] ?? 0,
                    'data' => $requestBodyData ?? '',
                    'ctime' => time(),
                ]);
            } else if ($eventType == 2 || $eventType == 3 || $eventType == 42) {
                $notify_copy_id = NotifyCopy::query()->insertGetId([
                    'event_type' => $eventType,
                    'uid' => $requestBody['accid'] ?? 0,
                    'timestamp' => $requestBody['timestamp'] ?? 0,
                    'data' => $requestBodyData ?? '',
                    'ctime' => time(),
                ]);
            } else if ($eventType == 5) {
                $insertData = $requestBody['data'];
                $notify_copy_id = NotifyCopy::query()->insertGetId([
                    'event_type' => $eventType,
                    'uid' => empty($insertData) ? 0 : $insertData['uid'],
                    'channel' => empty($insertData) ? 0 : $insertData['channelName'],
                    'timestamp' => $requestBody['timestamp'] ?? 0,
                    'data' => $requestBodyData ?? '',
                    'ctime' => time(),
                ]);
            } else {
                $notify_copy_id = NotifyCopy::query()->insertGetId([
                    'event_type' => $eventType,
                    'data' => $requestBodyData ?? '',
                    'ctime' => time(),
                ]);
            }

            if (!$wyyClient->verifyCheckSum($MD5, $CurTime, $CheckSum)) {
                if (!empty($notify_copy_id)) {
                    NotifyCopy::query()->where('id', $notify_copy_id)->update(['flag' => 1]);
                }
                return $wyyClient->responseJson(1, 200, "签名错误");
            }

            //登录事件
            if ($eventType === 2) {
                $uid = $requestBody["accid"];
                FunUtil::socket_client('login', $uid, "", "");
                $wyyClient->user_online($uid, 1);
            }

            //登出事件
            if ($eventType === 3) {
                $uid = $requestBody["accid"];
                $wyyClient->user_online($uid, 0);

                // TODO 还有问题，暂时取消
                // 通知对方客户端视频挂断
                // $payCall=(new PayCallModel())->find('id',"user_id=? or anchor_id=?",[$uid,$uid]);
                // if(!empty($payCall)){
                //     (new PaycallAction())->noticeOtherHangUp($payCall['id'],$uid);
                // }
                FunUtil::socket_client('logout', $uid, "", "");
            }

            //音视频进入房间
            if ($eventType === 4) {
                $uid = $requestBody["data"]["uid"];
                $call_id = $requestBody["data"]["channelName"];
                // $userModel->updateByWhere(array('online' => 2), "id = $uid");
                User::query()->where('id', $uid)->update(['online' => 2]);
                $wyyClient->user_online($uid, 2);
            }

            //音视频退出房间
            if ($eventType === 5) {
                $uid = $requestBody["data"]["uid"];
                $call_id = $requestBody["data"]["channelName"];
                // $res = $userModel->updateByWhere(array('online' => 1), "id = $uid and online=2");
                $res = User::query()->where('id', $uid)->where('online', 2)->update(['online' => 1]);
                if ($res) {
                    $wyyClient->user_online($uid, 1);
                }
                // 通知对方客户端视频挂断
                (new PaycallAction())->noticeOtherHangUp($call_id, $uid);
                // (new PaycallAction())->noticeOtherHangUp($call_id,$uid);
                // delayJob("checkCallExitRoom",[$call_id,$uid],2);

                $redis->del("call_user_ad:{$call_id}_{$uid}");
            }

            // 心跳事件
            if ($eventType === 42) {
                $uid = $requestBody["accid"];
                FunUtil::socket_client('ping', $uid, "", "");
            }

            // 音视频退出房间
            if ($eventType === 400) {
                $call_id = $requestBody["data"]["channelName"];
                $evidences = $requestBody["data"]["evidences"];

                $img = "";
                $uid = "";
                $label = "";
                $subLabel = '';
                $type = "";
                $level = 0;
                $rate = 0;
                if (isset($evidences['audio'])) {
                    $img = $evidences['audio']['content'];
                    $uid = $evidences['audio']['uid'];
                    $label = $evidences['audio']['segments'][0]['label'];
                    $level = $evidences['audio']['segments'][0]['level'];
                    $subLabel = $evidences['audio']['segments'][0]['subLabels'][0]['subLabel'];
                    $type = "audio";

                    $data = [
                        'task_id' => $requestBody['data']['taskId'] ?? '',
                        'data_id' => $requestBody['data']['dataId'] ?? '',
                        'channel_id' => $requestBody['data']['channelId'] ?? '',
                        'channel_name' => $requestBody['data']['channelName'] ?? '',
                        'status' => $requestBody['data']['status'] ?? 0,
                        'censor_source' => $requestBody['data']['censorSource'] ?? 0,
                        'uid' => $evidences['audio']['uid'] ?? 0,
                        'action' => $evidences['audio']['action'] ?? 0,
                        'asr_status' => $evidences['audio']['asrStatus'] ?? 0,
                        'content' => $evidences['audio']['content'] ?? '',
                        'label' => $evidences['audio']['segments'][0]['label'] ?? 0,
                        'level' => $evidences['audio']['segments'][0]['level'] ?? 0,
                        'sub_label' => $evidences['audio']['segments'][0]['subLabels'][0]['subLabel'] ?? 0,
                        'evidence' => $evidences['audio']['segments'][0]['subLabels'][0]['details']['evidence'] ?? '',
                        'start_time' => ($evidences['audio']['startTime'] ?? 0) / 1000,
                        'end_time' => ($evidences['audio']['endTime'] ?? 0) / 1000,
                        'ctime' => time(),
                    ];
                    // $userModel->insert($data, 'tb_yunxin_audio');
                    YunxinAudio::query()->insert($data);
                }
                if (isset($evidences['video'])) {
                    $img = $evidences['video']['evidence']['url'];
                    $uid = $evidences['video']['evidence']['uid'];
                    $label = $evidences['video']['labels'][0]['label'];
                    $level = $evidences['video']['labels'][0]['level'];
                    $rate = $evidences['video']['labels'][0]['rate'];
                    $subLabel = $evidences['video']['labels'][0]['subLabels'][0]['subLabel'];
                    $type = "video";

                    $data = [
                        'task_id' => $requestBody['data']['taskId'] ?? '',
                        'data_id' => $requestBody['data']['dataId'] ?? '',
                        'channel_id' => $requestBody['data']['channelId'] ?? '',
                        'channel_name' => $requestBody['data']['channelName'] ?? '',
                        'status' => $requestBody['data']['status'] ?? 0,
                        'censor_source' => $requestBody['data']['censorSource'] ?? 0,
                        'uid' => $evidences['video']['evidence']['uid'] ?? 0,
                        'url' => $evidences['video']['evidence']['url'] ?? '',
                        'label' => $evidences['video']['labels'][0]['label'] ?? 0,
                        'level' => $evidences['video']['labels'][0]['level'] ?? 0,
                        'rate' => $evidences['video']['labels'][0]['rate'] ?? 0,
                        'sub_label' => $evidences['video']['labels'][0]['subLabels'][0]['subLabel'] ?? 0,
                        'sub_rate' => $evidences['video']['labels'][0]['subLabels'][0]['rate'] ?? 0,
                        'begin_time' => ($evidences['video']['evidence']['beginTime'] ?? 0) / 1000,
                        'end_time' => ($evidences['video']['evidence']['endTime'] ?? 0) / 1000,
                        'ctime' => time(),
                    ];
                    // $userModel->insert($data, 'tb_yunxin_video');
                    YunxinAudio::query()->insert($data);
                }

                if ($img) {
                    $userInfo = User::query()->where('uid', $uid)->first();
                    $userInfo = modelToArray($userInfo);
                    $payCall = PayCallDao::getInstance()->getCallCache($call_id, true);
                    $user_id = $payCall['user_id'] == $uid ? $payCall['anchor_id'] : $payCall['user_id'];
                    $insertData = array(
                        'uid' => $uid,
                        'user_id' => $user_id,
                        'type' => $type,
                        'img' => $img,
                        'label' => $label,
                        'call_id' => $call_id,
                        'status' => 0,
                        'ctime' => time(),
                        'from' => intval($userInfo['from']),
                        'version_code' => intval($userInfo['version_code']),
                        'channel' => trim($userInfo['channel']),
                    );
                    MongoDBClient::getInstance()->insert('tb_paycall_screen', $insertData);

                    // 100：色情，110：性感；200：广告，210：二维码，260：广告法，300：暴恐，400：违禁，500：涉政，800：恶心类，900：其他，1020：黑屏，1030：挂机，1100：涉价值观。
                    if (in_array($label, [100, 110, 200, 210, 260, 300, 400, 500, 800, 900, 1020, 1100])) {
                        LoggerUtil::write("yun_xin_copy_safe", $requestBody);
                    }

                    // 主播广告禁言处理
                    if (in_array($subLabel, ['20001', '20002', '20003', '20004', '200009', '200268', '21000', '210023'])) {
                        // if($label == 200 && in_array($subLabel,['200009','200268','260056','260057','260281'])){
                        // //广告直接挂断
                        // if($uid == $payCall['user_id']){
                        //     (new PaycallAction())->hangUpCall($call_id, $uid, 9);
                        // }else{
                        //     (new PaycallAction())->hangUpCall($call_id, $uid, 10);
                        // }

                        // // 发现1次马上处理
                        // $redis=(new RedisConn())->getConn();
                        // $ad_tag = $redis->get("call_user_ad:{$call_id}_{$uid}");
                        // if(intval($ad_tag)<1){
                        //    $redis->setex("call_user_ad:{$call_id}_{$uid}",30*60,intval($ad_tag)+1);
                        // }else{

                        if ($uid != $payCall['user_id']) {
                            // 女用户禁言
                            // $userService->banned($uid,"通话中广告禁言");
                            // 记录用户处罚结果
                            $insertData = [
                                'uid' => $uid,
                                'call_id' => $call_id,
                                'punish_type' => 0,
                                'hit_type' => $type,
                                'content' => $img,
                                'task_id' => $requestBody['taskId'],
                                'ctime' => time(),
                            ];
                            UserPunish::query()->insert($insertData);
                        }
                        // 通话中2次直接挂断通话
                        $h = date('Hi');
                        if ($h >= '0200' and $h <= '0930') {
                            (new PaycallAction())->hangUpCall($call_id, $uid, 10);
                        }
                        // }
                        LoggerUtil::write("yun_xin_copy_user_punish", ["uid" => $uid, 'type' => $type, 'call_id' => $call_id, 'content' => $img]);
                    }
                    if ($label == 100 && $type == 'video') {
                        // $sql = "SELECT status FROM tb_ad_unmask WHERE uid=$uid";
                        // $unmask = $userModel->findOneField($sql, 'status');
                        $unmask = AdUnmask::query()->where('uid', $uid)->value('status');
                        if ($unmask != 1) {
                            User::query()->where('id', $uid)->update(['special_tag' => 1]);
                            // 判断当前用户是否开启黑屏
                            $call_break_rules = $redis->get("call_break_rules:{$call_id}_{$uid}");
                            if (!$call_break_rules) {
                                $redis->setex("call_break_rules:{$call_id}_{$uid}", 10, 1);

                                // delayJob("checkBreakRules", [$call_id, $uid], 12);
                                $queueData = ['call_id' => $call_id, 'uid' => $uid];
                                pushDelayJob(RemoveBlackScreenDelayQueueJob::class, $queueData, 12);

                                $rs = Setting::query()->select('call_mask_rate', 'call_mask_type')->first();
                                $settingRate = $rs['call_mask_rate'];
                                $call_mask_type = $rs['call_mask_type'];
                                if ($call_mask_type == 0) {
                                    if ($uid == $payCall['user_id']) {
                                        // 黑屏对方  男违规不管分数
                                        (new PaycallAction())->sendBlackScreenMsg($payCall['user_id'], $payCall['anchor_id'], $call_id, $payCall['type']);
                                    } elseif ($rate >= $settingRate) {
                                        // 黑屏对方 女违规需大于设定的分数
                                        (new PaycallAction())->sendBlackScreenMsg($payCall['anchor_id'], $payCall['user_id'], $call_id, $payCall['type']);
                                    }
                                } elseif ($call_mask_type == 1 && $uid == $payCall['user_id']) {
                                    //黑屏对方
                                    (new PaycallAction())->sendBlackScreenMsg($payCall['user_id'], $payCall['anchor_id'], $call_id, $payCall['type']);
                                } elseif ($call_mask_type == 2 && $uid != $payCall['user_id'] && $rate >= $settingRate) {
                                    //黑屏对方
                                    (new PaycallAction())->sendBlackScreenMsg($payCall['anchor_id'], $payCall['user_id'], $call_id, $payCall['type']);
                                }
                            } else {
                                $redis->setex("call_break_rules:{$call_id}_{$uid}", 10, 1);
                                pushDelayJob("checkBreakRules", [$call_id, $uid], 12);
                            }
                        }
                    }
                }
            }

            // 1 即会话类型的消息; PERSON（单聊会话内消息）
            if ($eventType != 1 || $convType != "PERSON") {
                if (!empty($notify_copy_id)) {
                    // $userModel->updateByWhere(['flag' => 1], "id=$notify_copy_id", 'tb_notify_copy');
                    NotifyCopy::query()->where('id', $notify_copy_id)->update(['flag' => 1]);
                }
                return $wyyClient->responseJson(0, 20000, "", []);
            }

            $uid = $requestBody["fromAccount"];
            $user_id = $requestBody["to"];
            $ext = $requestBody["ext"];
            $ext = json_decode($ext, true);

            //消息类型
            $contentTypeArr = [
                "TEXT" => 1,
                "AUDIO" => 2,
                "PICTURE" => 3,
            ];
            $content_type = $ext["msg"][0]["content_type"]; //1 文本 2 语音 3 图片
            $chat_type = $ext["msg"][0]["chat_type"];
            $content = $ext["msg"][0]["content"];
            if (isset($ext['msg'][0]['user_info']['language']) && $ext['msg'][0]['user_info']['language'] != '') {
                $language = $ext['msg'][0]['user_info']['language'];
            } else {
                $ext2 = User::query()->where('uid', $uid)->value('ext2');
                $uExt2Array = json_decode($ext2);
                $language = $uExt2Array['language'] ?? 'en';
            }

            if (in_array($content_type, [2, 3]) && !str_starts_with($content, 'http')) {
                $attach = $requestBody["attach"];
                $attach = json_decode($attach, true);
                $content = $attach["url"];
            }

            if (!in_array($chat_type, [3, 4, 5, 12])) {
                if (!empty($notify_copy_id)) {
                    // $userModel->updateByWhere(['flag' => 1], "id=$notify_copy_id", 'tb_notify_copy');
                    NotifyCopy::query()->where('id', $notify_copy_id)->update(['flag' => 1]);
                }
                return $wyyClient->responseJson(0, 20000, "", []);
            }

            //易盾审核建议
            $yidunRes = $requestBody["yidunRes"];
            LoggerUtil::write('yun_xin_copy_yi_dun', $yidunRes);//11
            $yidunRes = json_decode($yidunRes, true);
            $result = json_decode($yidunRes['result'], true);
            $label = 0;
            if ($content_type === 1) {
                $taskId = $result['antispam']['taskId'];
                $suggestion = $result['antispam']['suggestion'];
                if (sizeof($result['antispam']['labels']) > 0 && $suggestion > 0) {
                    $label = $result['antispam']['labels'][0]['label'];
                }
            } else {
                $taskId = $result[0]['antispam']['taskId'];
                $suggestion = $result[0]['antispam']['suggestion'];
                if (sizeof($result[0]['antispam']['labels']) > 0 && $suggestion > 0) {
                    $label = $result[0]['antispam']['labels'][0]['label'];
                }
            }
            $suggestion = intval($suggestion);

            $userInfo = User::where('id', $uid)->first();
            $userInfo = modelToArray($userInfo);

            $over_time = strtotime(date("Y-m-d") . " 23:59:59") - time();
            if ($userInfo['sex'] == 1) {
                $redis->setex("chat_man_reply:{$uid}", $over_time, -1);
            } else {
                $count = $redis->get("chat_man_reply:{$user_id}");
                if (intval($count) >= 0) {
                    if ($count && $count > 10) {
                        // 发送短信
                        $redis->setex("chat_man_reply:{$user_id}", $over_time, -1);
                    } else {
                        $redis->setex("chat_man_reply:{$user_id}", $over_time, intval($count) + 1);
                    }
                }
            }


            if ($userInfo['sex'] == 2) { // 女用户对男用户发
                if ($chat_type == 3) { //聊天类型为红线
                    // $userModel->recordFirstAccost($uid, $user_id, 3);// 1一键搭讪  2手动搭讪  3红线  4主页私信  5上线私信
                    (new UserFirstAccost())->recordFirstAccost($uid, $user_id, 3);
                }
                if ($chat_type == 4) { //聊天类型为私信
                    (new UserFirstAccost())->recordFirstAccost($uid, $user_id, 4);// 1一键搭讪  2手动搭讪  3红线  4主页私信  5上线私信
                }
            }

            $chatData = [
                'uid' => $uid,
                'user_id' => $user_id,
                'content' => $content,
                'from' => $requestBody["fromClientType"] == "IOS" ? 2 : 1,
                'msg_type' => 2,
                'content_type' => $content_type,
                'type' => $chat_type,
                'channel_number' => $userInfo['channel'],
                'guild_num' => trim($userInfo['guild_num']),
                'version_code' => $userInfo['version_code'],
                'suggestion' => $suggestion,
                'label' => $label,
                'taskId' => $taskId,
                'message_id' => $ext["msg"][0]["message_id"],
                'sync_sender' => $ext['msg'][0]['sync_sender'],
                'message_price' => $ext["msg"][0]['message_price'],
                'is_error' => $ext['msg'][0]['is_error'] ?? 0,
            ];

            if ($content_type == 1 || $content_type == 2 || $content_type == 3) { // 文本 / 音频 / 图片
                $chatData['suggestion'] = $ext['msg'][0]['suggestion'];
                $chatData['label'] = $ext['msg'][0]['suggestionMsg'];
                $chatData['taskId'] = $ext['msg'][0]['taskID'];
            }
            if ($content_type == 2) { // 音频消息额外携带音频识别文本
                $chatData['audio_text'] = (string)@$ext['msg'][0]['audioText'];
            }

            $insertRs = (new MessageAction())->insertUserChat($chatData);
            //标记最后拉取时间
            $toInfo = User::query()->where('id', $user_id)->first();
            $toInfo = modelToArray($toInfo);
            $micotime = microtime(true);
            UserChatFlagDao::getInstance()->updateLastTimeFlag($user_id, $toInfo['imei'], $micotime);

            // 易盾拦截消息扣费
            // 2023-04-26 违规消息不扣费了
            // if($suggestion == 2 && in_array($chat_type, [3, 4, 5])){
            // 	if(!(new Follow2Model())->isMutual($uid,$user_id)){
            // 		//判断用户剩余金币
            // 		$text_price=(new AnchorModel())->getValue($user_id,"greet_price");
            // 		if ($userModel->getValue($uid, "gift_count+chat_count+recharge_send_count+sys_send_count") >= $text_price) {
            // 			//扣除男用户金币
            // 			$res = (new PaycallAction())->payForMessage($uid, $user_id, $text_price, SINGLE_MESSAGE_RATE,$ext['msg'][0]["message_id"],0,1);
            // 		}
            // 	}
            // }


            if ($chat_type == 4) {
                MissionQueue::reply($uid);
                MissionQueue::fate($uid, $user_id);

                //(new \YdClient())->checkProfile($uid, $user_id, $content, $userInfo['phone'], $userInfo['register_ip']);
            }
            if (in_array($chat_type, [3, 4, 5])) {
                MissionQueue::stat($uid, $user_id, $chat_type);
            }

            //标记消息已回复
            // $insertRs = $userModel->setActionReply($uid, $user_id);
            LogScript::query()->where('uid', $uid)->where('anchor_id', $user_id)->where('action_reply', 0)
                ->update(['action_reply' => 1]);

            // $userOnline = $userModel->isOnline($user_id);
            $userOnline = User::query()->where('id', $user_id)->value('online');


            // $userToken = $userModel->find("uid,status,package", "uid=?", [$user_id], '', 'tb_user_token');
            $userToken = UserToken::query()->select(['uid', 'status', 'package'])->where('uid', $user_id)->first();
            // 友盟推送消息
            if ($user_id > 0 && in_array($content_type, [1, 2, 3]) && $suggestion === 0) {
                switch ($content_type) {
                    case 2:
                        $message = '[' . trans('message.语音消息', [], $language) . ']';
                        break;
                    case 3:
                        $message = '[' . trans('message.图片消息', [], $language) . ']';
                        break;
                    default:
                        $message = $content;
                        break;
                }
                //logInfo('notify_copy', ["message" => "信鸽推送",]);
                // 1一键搭讪  2手动搭讪  3红线  4主页私信  5上线私信
                if ($chat_type == 4) {
                    // $sql = ($userInfo['sex'] == 1)
                    //     ? "SELECT id FROM tb_closeness WHERE uid=$uid AND anchor_id=$user_id AND score>=5"
                    //     : "SELECT id FROM tb_closeness WHERE uid=$user_id AND anchor_id=$uid AND score>=5";
                    // $rs = $userModel->findOne($sql);
                    if ($userInfo['sex'] == 1) {
                        $exists = Closeness::query()->where('uid', $uid)->where('anchor_id', $user_id)->where('score', '>=', 5)->exists();
                    } else {
                        $exists = Closeness::query()->where('uid', $user_id)->where('anchor_id', $uid)->where('score', '>=', 5)->exists();
                    }
                    if ($exists) {
                        // (new Push())->putPushMsgQueue($user_id, $userInfo['nickname'] . ' : ' . $message, $userToken['package']);
                        PushMessageService::putUMengMsgQueue($user_id, $userInfo['nickname'] . ' : ' . $message, $userToken['package']);
                    }
                } else {
                    if ($userOnline == 0) {
                        // 离线用户消息每天最多推送3次消息
                        $pushCount = intval($redis->get("not_oline_push:user_" . $user_id));
                        if ($pushCount < 3) {
                            // (new Push())->putPushMsgQueue($user_id, $userInfo['nickname'] . ' : ' . $message, $userToken['package']);
                            PushMessageService::putUMengMsgQueue($user_id, $userInfo['nickname'] . ' : ' . $message, $userToken['package']);
                            $time = strtotime(date("Y-m-d") . " 23:59:59") - time();
                            $redis->set("not_oline_push:user_" . $user_id, $pushCount + 1, $time);
                        }
                    } elseif ($userToken['status'] == 1) {
                        // 后台用户间隔5分钟推送一次
                        $pushFlag = $redis->get('backend_user_push_' . $user_id);
                        if (!$pushFlag) {
                            // (new Push())->putPushMsgQueue($user_id, $userInfo['nickname'] . ' : ' . $message, $userToken['package']);
                            PushMessageService::putUMengMsgQueue($user_id, $userInfo['nickname'] . ' : ' . $message, $userToken['package']);
                            $redis->set('backend_push:user_' . $user_id, time(), 5 * 60);
                        }
                    }
                }
            }
            if (!empty($notify_copy_id)) {
                // $userModel->updateByWhere(['flag' => 1], "id=$notify_copy_id", 'tb_notify_copy');
                NotifyCopy::query()->where('id', $notify_copy_id)->update(['flag' => 1]);
            }
            return $wyyClient->responseJson(0, 20000, "Save Msg ok.");

        } catch (Throwable $e) {
            LoggerUtil::write('yun_xin_copy', [
                'type' => 'exception',
                "message" => $e->getMessage(),
                "file" => $e->getFile(),
                "line" => $e->getLine(),
            ]);
            return $wyyClient->responseJson(1, 200, $e->getMessage());
        }

    }


}